"""
ChatterBot utility functions
聊天机器人的实用功能
"""


def import_module(dotted_path):
    """
    Imports the specified module based on the
    dot notated import path for the module.
    导入指定的模块的基础上
    点表示进口路径模块。
    """
    import importlib

    module_parts = dotted_path.split('.')
    module_path = '.'.join(module_parts[:-1])
    module = importlib.import_module(module_path)

    return getattr(module, module_parts[-1])


def initialize_class(data, **kwargs):
    """
    :param data: A string or dictionary containing a import_path attribute.
    ：参数：字符串或数据字典包含import_path属性。
    """
    if isinstance(data, dict):
        import_path = data.pop('import_path')
        data.update(kwargs)
        Class = import_module(import_path)

        return Class(**data)
    else:
        Class = import_module(data)

        return Class(**kwargs)


def validate_adapter_class(validate_class, adapter_class):
    """
    Raises an exception if validate_class is not a
    subclass of adapter_class.

    :param validate_class: The class to be validated.
    :type validate_class: class

    :param adapter_class: The class type to check against.
    :type adapter_class: class

    :raises: Adapter.InvalidAdapterTypeException
    提出了一个例外，如果validate_class不是
    类adapter_class。
    ：参数validate_class：类来验证。
    validate_class类：类型：
    adapter_class：参数：类类型的对照。
    adapter_class类：类型：
    ：提出：adapter.invalidadaptertypeexception
    """
    from .adapters import Adapter

    # If a dictionary was passed in, check if it has an import_path attribute
    #如果字典是通过，检查它是否有一个import_path属性
    if isinstance(validate_class, dict):
        origional_data = validate_class.copy()
        validate_class = validate_class.get('import_path')

        if not validate_class:
            raise Adapter.InvalidAdapterTypeException(
                'The dictionary {} must contain a value for "import_path"'.format(
                    str(origional_data)
                )
            )

    if not issubclass(import_module(validate_class), adapter_class):
        raise Adapter.InvalidAdapterTypeException(
            '{} must be a subclass of {}'.format(
                validate_class,
                adapter_class.__name__
            )
        )


def input_function():
    """
    Normalizes reading input between python 2 and 3.
    The function 'raw_input' becomes 'input' in Python 3.
    对Python 2和3之间的阅读输入。
    功能的raw_input '变成了'在Python 3输入。
    """
    import sys

    if sys.version_info[0] < 3:
        user_input = str(raw_input()) # NOQA

        # Avoid problems using format strings with unicode characters
        #使用Unicode字符的格式字符串避免问题
        if user_input:
            user_input = user_input.decode('utf-8')

    else:
        user_input = input() # NOQA

    return user_input


def nltk_download_corpus(resource_path):
    """
    Download the specified NLTK corpus file
    unless it has already been downloaded.

    Returns True if the corpus needed to be downloaded.
    下载指定文件NLTK语料库
    除非它已经被下载了。
    如果需要下载语料，返回true。
    """
    # from nltk.data import find
    # from nltk import download
    from os.path import split, sep
    from zipfile import BadZipfile

    # Download the NLTK data only if it is not already downloaded
    #下载NLTK数据如果尚未下载

    _, corpus_name = split(resource_path)

    # From http://www.nltk.org/api/nltk.html
    # When using find() to locate a directory contained in a zipfile,
    # the resource name must end with the forward slash character.
    # Otherwise, find() will not locate the directory.
    #
    # Helps when resource_path=='sentiment/vader_lexicon''
    #从http://www.nltk.org/api/nltk.html #
    #时使用（）来定位一个目录包含一个zip文件，
    #资源名称必须以正斜杠字符。
    #否则，（）不会定位目录。
    #
    #帮助resource_path = = 'sentiment / vader_lexicon”
    if not resource_path.endswith(sep):
        resource_path = resource_path + sep

    downloaded = False

    try:
        # find(resource_path)
        pass
    except LookupError:
        # download(corpus_name)
        downloaded = True
    except BadZipfile:
        raise BadZipfile(
            'The NLTK corpus file being opened is not a zipfile, '
            'or it has been corrupted and needs to be manually deleted.'
        )

    return downloaded


def remove_stopwords(tokens, language):
    """
    Takes a language (i.e. 'english'), and a set of word tokens.
    Returns the tokenized text with any stopwords removed.
    Stop words are words like "is, the, a, ..."
    获取一种语言（即“英语”）和一组单词标记。
    返回标记文本的任何停用词去除。
    停止单词是像“是，是，是，……”这样的词。
    """
    from nltk.corpus import stopwords

    # Get the stopwords for the specified language
    #得到stopwords为指定的语言
    stop_words = stopwords.words(language)

    # Remove the stop words from the set of word tokens
    #去除停用词从词标记集
    tokens = set(tokens) - set(stop_words)

    return tokens


def get_response_time(chatbot):
    """
    Returns the amount of time taken for a given
    chat bot to return a response.

    :param chatbot: A chat bot instance.
    :type chatbot: ChatBot

    :returns: The response time in seconds.
    :rtype: float
    返回给定时间所花费的时间。
    聊天机器人返回一个响应。
    ：聊天：聊天机器人实例参数。
    类型：聊天的聊天机器人：
    返回：以秒为单位的响应时间。
    ：R型：浮
    """
    import time

    start_time = time.time()

    chatbot.get_response('Hello')

    return time.time() - start_time


def generate_strings(total_strings, string_length=20):
    """
    Generate a list of random strings.

    :param total_strings: The number of strings to generate.
    :type total_strings: int

    :param string_length: The length of each string to generate.
    :type string_length: int

    :returns: The generated list of random strings.
    :rtype: list
    生成随机字符串列表。
    ：参数total_strings：生成字符串的个数。
    ：total_strings：int类型
    ：参数string_length：生成每个字符串的长度。
    ：string_length：int类型
    ：返回：随机字符串生成的列表。
    R型：列表：
    """
    import random
    import string

    statements = []
    for _ in range(0, total_strings):
        text = ''.join(
            random.choice(string.ascii_letters + string.digits + ' ') for _ in range(string_length)
        )
        statements.append(text)
    return statements
